/**
@file
	Main.cpp
@brief

@author
	GengYong
@revision
	2005/11/05 * Created by GengYong.
*/

#include "StdUtility.h"
#include "KernelLoader.h"
#include "KernelImpl.h"
#include "LogDevice.h"
using namespace SAF;


struct CommandCatalogTable
{
	SAF::IServiceModule *	service;
	SAF::StateBits			statebits;
} catalogTable[65536];

extern "C" int getch();

int main(int argc, char*argv[])
{
	REGISTER_PERFCOUNTER("SAFKernel");

	if (argc <= 1)
	{
		printf("USAGE:\n\t%s %s\n", argv[0], "CONFIGFILE");
		return 0;
	}

	KernelLoader::Instance().LoadFromFile(argv[1]);
	const IKernel * kernel = KernelLoader::Instance().Kernel();
	if (kernel != 0)
	{
		SAFDBG("[SAF] Starting SAF, Please waiting...");

		IMessageRouter ** msgslot = 0;
		IServiceModule ** svcslot = 0;

		int svcmodcount = kernel->GetServiceModuleList(svcslot);
		int msgdevcount = kernel->GetMessageRouterList(msgslot);

		//initialize...
		{
			for (int index = 0; index < sizeof(catalogTable)/sizeof(catalogTable[0]); index++)
			{
				catalogTable[index].service		= 0;
				catalogTable[index].statebits	= 0;
			}

			for (int index = 0; index < svcmodcount; index++)
			{
				int catalogId = kernel->GetServiceModuleCatalog(index);
				catalogTable[catalogId].service		= svcslot[index];
				catalogTable[catalogId].statebits	= kernel->GetServiceModuleStateBits(index);
			}
		}

		//running...
		{			
			SAFLOG("[SAF] SAF Server start running...\r\n");

			unsigned long time	= 0;
			IConnection * conn	= 0;
			NetPackage packet;
			
			for (;;)
			{
				time = Util::Util_GetTime();

				try
				{
					for (int i = 0; i < msgdevcount; i++)
					{
						if (msgslot[i]->RecvNetMessage(conn, packet, time))
						{
							if (catalogTable[packet.message.catalog].statebits & conn->State())
							{
								catalogTable[packet.message.catalog].service->Process(conn, packet);
							}
							else
							{
								SAFERR("[SAF] Received a message with miss state! service[catalog:%d]:0x%llX <==> node:0x%llX, message:%d.",
									packet.message.catalog,
									catalogTable[packet.message.catalog].statebits,
									conn->State(), 
									packet.message.command);
							}
						}
					}
				}
				catch(SAF::KERNEL::KERNELEXCEPTION<SAF::KERNEL::EXCEPTIONCODE::TERMINATE_REQUEST>)
				{
					break;
				}
				catch(...)
				{
					SAFERR("[SAF] Warning: catch an unhandled exception !!!");
				}
			}
		}
		Util::Util_WaitTime(3000);
	}
	return 0;
}

